package io.nanfeng.scope

import java.io.File
import java.io.FileInputStream
import java.io.InputStream

// 1
interface AutoCloseScope {
    fun defer(closeBlock: () -> Unit)
    fun close()
}

// 2
context(AutoCloseScope)
fun File.open(): InputStream {
    if (!this.exists()) {
        this.createNewFile()
    }
    val inputStream: FileInputStream = this@File.inputStream()
    defer { inputStream.close() }
    return inputStream
}

// 3
fun withAutoClose(block: context(AutoCloseScope) () -> Unit) {
    val scope = AutoCloseScopeImpl()
    try {
       block(scope)
    } finally {
        scope.close()
    }
}

// 4
class AutoCloseScopeImpl : AutoCloseScope {
    private val closeable = mutableListOf<() -> Unit>()

    override fun defer(closeBlock: () -> Unit) {
        closeable += closeBlock
    }

    override fun close() = closeable.asReversed().forEach { it.invoke() }
}

fun main() {
    // 5 usage
    withAutoClose {
        val input = File("input.txt").open()
        val config = File("config.txt").open()
    }
}